﻿using System;
using System.Collections.Generic;
using System.Reflection;
using CoreDES.Modeling;



namespace MBT.Modeling
{
    public class AtomicTestModel
    {
        public int modelLevel;

        //circular submodels are not OK!
        public List<AtomicTestModel> submodels = new List<AtomicTestModel>();
        public List<object> submodelObjects = new List<object>();

        //circular reference is OK
        public List<AtomicTestModel> refrencedModels = new List<AtomicTestModel>();
        public List<object> refrencedModelObjects = new List<object>();
        //But the reference object should be "Read" in the array of models!





        /// <summary>
        /// Executable object
        /// </summary>
        public object ExecutableObject = null;
        /// <summary>
        /// Type of executable object
        /// </summary>
        public Type stateType;

        public AtomicTestModel()
        {

        }

        public AtomicTestModel(object executableObject)
        {
            //Extract information from object Here
        }
        List<TestEvent> events = new List<TestEvent>();

        #region DES Based structures
        protected VaribalesCollection vars = new VaribalesCollection();
        //protected EventsCollection4Test events = new EventsCollection4Test();
        //protected AUXsCollection4Testing aux = new AUXsCollection4Testing();
        //protected RewardsCollection rewards = new RewardsCollection();
        protected ModelSlicer slicer = new ModelSlicer();

        public VaribalesCollection Variables
        {
            get
            {
                return vars;
            }
        }
        public List<TestEvent> Events
        {
            get
            {
                return events;
            }
        }
        //public AUXsCollection4Testing AUX
        //{
        //    get
        //    {
        //        return aux;
        //    }
        //}
        //public RewardsCollection Rewards
        //{
        //    get
        //    {
        //        return rewards;
        //    }
        //}
        public ModelSlicer Slicer
        {
            get
            {
                return slicer;
            }
        }
        #endregion

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public bool postProcess()
        {
            //for (int i = 0; i < slicer.skipTransitionFunctions.Count; i++)
            //{
            //    for (int j = 0; j < events.Count; j++)
            //    {
            //        if (slicer.skipTransitionFunctions[i].Tag.Equals(events[j].ID))
            //        {
            //            events[j].precondition2 = slicer.skipTransitionFunctions[i];
            //            continue;
            //        }
            //    }
            //}
            return true;
        }



        #region Run-Time Methods
        //List<object> domains;
        bool executeDirectly = true;

        public bool isInFinalState
        {
            get
            {
                return false;
                //return (bool)ExecutableObject.GetType().InvokeMember("isFinalState", BindingFlags.InvokeMethod, null, ExecutableObject, null);
            }
        }

        public object GetCurrentState()
        {
            if (executeDirectly)
            {
                object currState = Activator.CreateInstance(stateType, ExecutableObject);
                return currState;
            }
            else
                return ExecutableObject.GetType().InvokeMember("CurrentState", BindingFlags.GetProperty, null, ExecutableObject, null);
        }

        public void SetCurrentState(object st)
        {
            if (executeDirectly)
            {
                stateType.InvokeMember("CloneTo", BindingFlags.InvokeMethod, null, st, new object[] { ExecutableObject });
            }
            else
            {
                ExecutableObject.GetType().InvokeMember("CurrentState", BindingFlags.SetProperty, null, ExecutableObject, new object[] { st });
            }
        }

        //public int GenerateDomains1(TestEvent e)
        //{
        //return e.RunNumberOfActionInstancesHandler();
        //if (!executeDirectly)
        //{
        //    return e.RunNumberOfActionInstancesHandler();
        //}

        //domains = new List<object>();
        //int size = 1;
        //for (int i = 0; i < e.NumberOfParams; i++)
        //{
        //    string funcName;
        //    string domianID;
        //    ((ExecFunction)e.ActionAttrib).paramDomains.TryGetValue(((ExecFunction)e.ActionAttrib).execParameters[i].ID, out domianID);
        //    slicer.domainFunctions.TryGetValue(domianID, out funcName);

        //    object dom = typeof(ExampleModel).
        //        InvokeMember(funcName, BindingFlags.InvokeMethod, null, ExecutableObject, null);
        //    System.Collections.IList collection = dom as System.Collections.IList;
        //    size *= collection.Count;
        //    domains.Add(collection);
        //}
        //return size;
        //}

        //public void RunActionHandler(TestEvent e, int instanceID)
        //{
        //    List<object> parameters = new List<object>();
        //    for (int i = 0; i < domains.Count; i++)
        //    {
        //        System.Collections.IList collection = domains[i] as System.Collections.IList;
        //        parameters.Add(collection[instanceID % collection.Count]);
        //        instanceID /= collection.Count;

        //    }
        //    //e.exeInfo.Invoke(ExecutableObject, BindingFlags.InvokeMethod, null, parameters.ToArray(),
        //    //    System.Globalization.CultureInfo.CurrentCulture);
        //    e.XRunActionHandler(parameters);
        //}
        //public bool RunPreconditionHandler(TestEvent e, int instanceID)
        //{
        //    //if (!executeDirectly)
        //    //{
        //    //    return e.RunPreconditionHandler(instanceID);
        //    //}
        //    List<object> parameters = new List<object>();
        //    for (int i = 0; i < domains.Count; i++)
        //    {
        //        System.Collections.IList collection = domains[i] as System.Collections.IList;
        //        parameters.Add(collection[instanceID % collection.Count]);
        //        instanceID /= collection.Count;

        //    }
        //    //return (bool)e.preInfo.Invoke(ExecutableObject, BindingFlags.InvokeMethod, null, parameters.ToArray(),
        //    //    System.Globalization.CultureInfo.CurrentCulture);
        //    return e.XRunPreconditionHandler(parameters);
        //}
        public void ValidateCurrentState()
        {
            if (!executeDirectly)
            {
                ExecutableObject.GetType().InvokeMember(
                                            "ValidateCurrentState", BindingFlags.InvokeMethod,
                                                 null, ExecutableObject, null);
            }
            else
            {
                //(bool)
                //((ExecFunction)slicer.SkipState).info.Invoke(ExecutableObject, BindingFlags.InvokeMethod, null, null,
                //    System.Globalization.CultureInfo.CurrentCulture);
            }
        }
        public bool isFinalState()
        {
            if (!executeDirectly)
            {
                return (bool)ExecutableObject.GetType().InvokeMember("isFinalState", BindingFlags.InvokeMethod, null, ExecutableObject, null);
            }
            else
            {
                return true;
            }
        }
        public bool SkipCurrentState()
        {
            if (!executeDirectly)
            {
                return (bool)ExecutableObject.GetType().InvokeMember(
                                        "skipState", BindingFlags.InvokeMethod,
                                             null, ExecutableObject, null);
            }
            else
            {
                return false;
            }
        }
        #endregion

        //        /// <summary>
        //        /// Read XML and Compile an executable Model!
        //        /// </summary>
        //        /// <param name="path"></param>
        //        public virtual void ReadXml(string path)
        //        {
        //            executeDirectly = false;
        //            XmlDatabaseHelper db = XmlDatabaseHelper.ReadXml(path);
        //            vars = VaribalesCollection4Test.ReadXML(db);
        //            events = EventsCollection4Test.ReadXML(db);
        //            rewards = RewardsCollection.ReadXML(db);
        //            aux = AUXsCollection4Testing.ReadXML(db);
        //            slicer = ModelSlicer.ReadXML(db);
        //            postProcess();

        //            #region Compile
        //            AtomicTestModel mysdes = this;
        //            System.IO.File.WriteAllText("c:\\tempModel.cs", generateCode());
        //            EnGine.CodeGeneration.CompilerHelper compiler = new EnGine.CodeGeneration.CompilerHelper("c:\\tempModel.cs", "MyNamespace.BaseSimulator");
        //            //model.
        //            //DoCompilation = true;
        //            foreach (string file in mysdes.AUX.Sources)
        //                compiler.AddSource(file);

        //            path = System.Reflection.Assembly.GetExecutingAssembly().Location;
        //            compiler.AddLibrary(path);
        //            compiler.Compile();
        //            ExecutableObject = compiler.CompiledObject;
        //            object loObject = compiler.CompiledObject;

        //            //return loResult;
        //            mysdes.Variables.SetInitializerHandler(
        //                   loObject.GetType().InvokeMember(
        //                    "Initial", BindingFlags.GetProperty,
        //                         null, loObject, null) as InitializerHandler);

        //            foreach (EventsCollection4Test.TestEvent e in mysdes.Events)
        //            {
        //                e.SetSimulationHandler(
        //                    loObject.GetType().InvokeMember(
        //                    e.ID + "_Pre", BindingFlags.GetProperty,
        //                         null, loObject, null) as EventsCollection4Test.TestEvent.PreConditionHandler,

        //                    loObject.GetType().InvokeMember(
        //                    e.ID + "_PreByParam", BindingFlags.GetProperty,
        //                         null, loObject, null) as EventsCollection4Test.TestEvent.PreConditionByParamHandler,
        //                    loObject.GetType().InvokeMember(
        //                    e.ID + "_Wei", BindingFlags.GetProperty,
        //                         null, loObject, null) as EventsCollection4Test.TestEvent.WeightHandler,
        //                    //loObject.GetType().InvokeMember(
        //                    //e.ID + "_Rnk", BindingFlags.GetProperty,
        //                    //     null, loObject, null) as EventsCollection.Event.RankHandler,
        //                    //loObject.GetType().InvokeMember(
        //                    //e.ID + "_Del", BindingFlags.GetProperty,
        //                    //     null, loObject, null) as EventsCollection.Event.ISDelayHandler,
        //                    loObject.GetType().InvokeMember(
        //                    e.ID + "_Act", BindingFlags.GetProperty,
        //                    null, loObject, null) as EventsCollection4Test.TestEvent.ActionHandler,

        //                    loObject.GetType().InvokeMember(
        //                    e.ID + "_ActByParam", BindingFlags.GetProperty,
        //                    null, loObject, null) as EventsCollection4Test.TestEvent.ActionByParamHandler,

        //                    loObject.GetType().InvokeMember(
        //                    e.ID + "_NOI", BindingFlags.GetProperty,
        //                         null, loObject, null) as EventsCollection4Test.TestEvent.NumberOfActionInstancesHandler);
        //                //loObject.GetType().InvokeMember(
        //                //e.ID + "_Rac", BindingFlags.GetProperty,
        //                //     null, loObject, null) as EventsCollection.Event.ReActivationHandler);
        //            }
        //            #endregion
        //        }

        //        public void Save(string path)
        //        {
        //            XmlDatabaseHelper db = new XmlDatabaseHelper();
        //            aux.WriteXML(db);
        //            vars.WriteXml(db);
        //            events.WriteXml(db);
        //            rewards.WriteXml(db);
        //            db.WriteXml(path);
        //        }

        //        /// <summary>
        //        /// Generate Code when the model is read from XML File
        //        /// </summary>
        //        /// <returns>Code of generated file</returns>
        //        public string generateCode()
        //        {
        //            AtomicTestModel mysdes = this;
        //            string generatedCode = "";
        //            //            object loObject;
        //            string StateCode = @" public class State
        //{";
        //            string Code = @"using System;
        //using System.Collections.Generic;
        //using EnGine.Base;
        //using EnGine.TestGine;
        //using EnGine.Formalism;
        //
        //namespace MyNamespace {
        //
        //public class BaseSimulator {
        ////    ExDistribution Distribution = new ExDistribution(true,1);
        //";
        //            #region vars
        //            //Code += mysdes.Variables.CreateSimulationCode4Sets();

        //            Code += mysdes.Variables.CreateSimulationCode4Variables();
        //            StateCode += mysdes.Variables.CreateSimulationCode4Variables();

        //            Code += "\n\tvoid initializeVariables()" + mysdes.Variables.Initilizer.Code;
        //            Code += "\n\tvoid initial(){initializeVariables();initializeDomains();}";
        //            //foreach (AUXsCollection4Testing. v in mysdes.Variables)

        //            Code += @"public EnGine.Formalism.Handlers.InitializerHandler Initial
        //            {
        //                get{
        //                    return new EnGine.Formalism.Handlers.InitializerHandler(initial);
        //                }
        //            }";
        //            Code += @"public State CurrentState
        //                        {
        //                            get{
        //                                State s = new State();int _i;
        //                            ";

        //            foreach (VaribalesCollection4Test.Variable v in mysdes.Variables)
        //            {
        //                if (v.VariableType.Contains("["))
        //                {
        //                    Code += "\n\tfor(_i=0;_i<" + v.ID + ".Length;_i++) " +
        //                        //"\n\t\tif (((object)" + v.ID + "[_i]) is IState) " +
        //                        //"s." + v.ID + " [_i]= (" + v.ProrammingVariableType + ")((((object)" +
        //                        //v.ID + "[_i]) as IState).Clone()); \n\t\telse" +
        //                                        "s." + v.ID + "[_i] = " + v.ID + "[_i];";
        //                }
        //                else
        //                {
        //                    Code += "s." + v.ID + " = " + v.ID + ";";
        //                }
        //            }

        //            Code += @"
        //                        return s;
        //                            }
        //                            set 
        //                            {
        //                               int _i;";

        //            //StateCode += "\n\tpublic State(){";
        //            foreach (VaribalesCollection4Test.Variable v in mysdes.Variables)
        //            {
        //                if (v.VariableType.Contains("["))
        //                {
        //                    Code += "\n\tfor(_i=0;_i<" + v.ID + ".Length;_i++)" + @" if (((object)" + v.ID + @"[_i]) is IState)
        //                    " + v.ID + " [_i] = (" + v.ProrammingVariableType.Substring(0, v.ProrammingVariableType.IndexOf("[]")) + ")((((object)value." + v.ID + @"[_i]) as IState).Clone());
        //                else
        //                    " + v.ID + " [_i] = value." + v.ID + " [_i];";
        //                }
        //                else
        //                {
        //                    Code += @" if (((object)" + v.ID + @") is IState)
        //                    " + v.ID + " = (" + v.ProrammingVariableType + ")((((object)value." + v.ID + @") as IState).Clone());
        //                else
        //                    " + v.ID + " = value." + v.ID + ";";
        //                }
        //            }
        //            //Code += "" + v.ID + " = value." + v.ID + ";";
        //            Code += @"
        //                            }
        //                        }";

        //            foreach (AUXsCollection4Testing.Constant c in mysdes.AUX.Constants)
        //            {
        //                StateCode += "\n\tconst " + c.Type + " " + c.ID + " = " + c.Value + ";";

        //            }
        //            StateCode += "\n\t//public static bool doGrouping = false;";
        //            StateCode += "\n\t//public bool sameGroupe(object dataOfEnums){ return false;}";
        //            //Also generate features-->Up
        //            #region State grouping [implemented by state featuers]
        //            if (mysdes.Variables.fetures.Count > 0)
        //            {
        //                for (int i = 0; i < mysdes.Variables.fetures.Count; i++)
        //                {
        //                    StateCode += "\n\tpublic " + mysdes.Variables.fetures[i].FeatureType + " " + mysdes.Variables.fetures[i].FeatureID +
        //                        "{ get " + mysdes.Variables.fetures[i].FeatureFunction + " }";
        //                }

        //                StateCode += @"  
        //    public override bool Equals(object dataOfEnums)
        //    {
        //        if(!(dataOfEnums is State))
        //            return base.Equals(dataOfEnums);
        //        State s = dataOfEnums as State;
        //        bool e = true;int _i,_j=0;";
        //                foreach (VaribalesCollection4Test.Feature f in mysdes.Variables.fetures)
        //                {
        //                    //What if more complex features?
        //                    StateCode += "\n\t\te = e & (" + f.FeatureID + ".Equals(s." + f.FeatureID + "));";
        //                }
        //                StateCode += @"
        //        return e;
        //    }
        //}
        //";
        //            }
        //            else
        //            {

        //                StateCode += @"  
        //    public override bool Equals(object dataOfEnums)
        //    {
        //        if(!(dataOfEnums is State))
        //            return base.Equals(dataOfEnums);
        //        State s = dataOfEnums as State;
        //        bool e = true;int _i,_j=0;";
        //                foreach (VaribalesCollection4Test.Variable v in mysdes.Variables)
        //                {
        //                    if (v.VariableType.Contains("["))
        //                    {
        //                        StateCode += "\n\t\tfor(_i=0;_i<" + v.ID + ".Length;_i++) e = e & (" + v.ID
        //                            + "[_i].Equals(s." + v.ID + "[_i]));";
        //                    }
        //                    else
        //                        StateCode += "\n\t\te = e & (" + v.ID + ".Equals(s." + v.ID + "));";
        //                }
        //                StateCode += @"
        //        return e;
        //    }
        //}
        //";
        //            }

        //            #endregion

        //            foreach (EventsCollection4Test.TestEvent e in mysdes.Events)
        //            {
        //                if (e.parameters.Count > 1)
        //                {
        //                    for (int i = 1; i < e.parameters.Count; i++)
        //                        Code += "\n\tList<" + e.parameters[i].type + "> " + e.ID + "_" + e.parameters[i].paramID + "_ParamList;";
        //                }
        //            }

        //            #endregion
        //            #region AUX
        //            foreach (Function f in mysdes.AUX.Functions)
        //            {
        //                Code += f.Type + " " + f.ID +
        //                " (";
        //                string param = "";
        //                foreach (EnGine.Formalism.Function.MethodParam p in f.Parameters)
        //                    param += p.Type + " " + p.ID + ",";
        //                param = (param == "") ? "" : param.Substring(0, param.Length - 1);
        //                Code += param + ")";
        //                Code += f.Code + "\n\r";
        //            }
        //            foreach (AUXsCollection4Testing.Constant c in mysdes.AUX.Constants)
        //            {
        //                Code += "\n\tconst " + c.Type + " " + c.ID + " = " + c.Value + ";";

        //            }
        //            string initDomain = "";

        //            Code += "\n/***************Domain Definition (if any)******************************/";
        //            foreach (Function domain in mysdes.AUX.Domains)
        //            {
        //                Code += "\n\treadonly List<" + domain.Type + "> " + domain.Tag + "= new List<" + domain.Type + ">();";
        //                Code += "\n\tvoid " + domain.Tag + "_domainGenerator()" + domain.Code;
        //                initDomain += "\n\t\t" + domain.Tag + "_domainGenerator();";
        //            }
        //            Code += "\n\tvoid initializeDomains(){" + initDomain + "}";

        //            #endregion

        //            #region Events
        //            foreach (EventsCollection4Test.TestEvent e in mysdes.Events)
        //            {
        //                Code += "\n/***********************************************************************/";

        //                if (e.parameters.Count == 1)
        //                {

        //                    Code += "\n\t\t" + e.ActionAttrib.Type + " " + e.ID + "_performAction()" + e.ActionAttrib.Code;
        //                    //Code += "\n\n\t\t" + e.ActionAttrib.Type + " " + e.ID + "_act(int instanceID){" + e.ID + "_performAction();}";
        //                    Code += "\n\n\tActionInfo " + e.ID + "_act(int instanceID){ActionInfo param=new ActionInfo(\"" + e.ID + "\"); " + e.ID + "_performAction(); return param;}";
        //                    Code += "\n\n\tActionInfo " + e.ID + "_actByParam(ActionInfo param){" + e.ID + "_performAction(); return param;}";

        //                    Code += "\n\t\tint " + e.ID + "_NoI(){return 1;}";

        //                    Code += "\n\n\t\t" + e.PreCondition.Type + " " + e.ID + "_performPre()" + e.PreCondition.Code;
        //                    if (e.precondition2 == null)
        //                    {
        //                        Code += "\n\n\t\t" + e.PreCondition.Type + " " + e.ID + "_pre(int instanceID){\n\t\t\treturn " + e.ID + "_performPre();}";
        //                        Code += "\n\n\t\t" + e.PreCondition.Type + " " + e.ID + "_preByParam(ActionInfo param){\n\t\t\treturn " + e.ID + "_performPre();}";
        //                    }
        //                    else
        //                    {

        //                        Code += "\n\n\t\t" + e.PreCondition.Type + " " + e.ID + "_pre(int instanceID){\n\t\t\treturn " + e.ID + "_performPre()&& " + e.ID + "_performPre2();}";
        //                        Code += "\n\n\t\t" + e.PreCondition.Type + " " + e.ID + "_preByParam(ActionInfo param){\n\t\t\treturn " + e.ID + "_performPre()&& " + e.ID + "_performPre2();}";
        //                    }

        //                }
        //                else
        //                {
        //                    string ActionCode = "\n\n\t\t" + e.ActionAttrib.Type + " " + e.ID + "_performAction(";
        //                    string PreCode = "\n\n\t\t" + e.PreCondition.Type + " " + e.ID + "_performPre(";

        //                    string nois = "\n\t\t\tint numberOfInstances = 1;";
        //                    string sl = "";
        //                    string extractParams = "";
        //                    string sl2 = "";
        //                    string paramList = "";
        //                    string paramString = "";
        //                    for (int i = 1; i < e.parameters.Count; i++)
        //                    {
        //                        if (i > 1)
        //                        {
        //                            ActionCode += ", " + e.parameters[i].type + " " + e.parameters[i].paramID;
        //                            PreCode += ", " + e.parameters[i].type + " " + e.parameters[i].paramID;
        //                            paramString += ", " + e.parameters[i].type + " " + e.parameters[i].paramID;
        //                            paramList += ", " + e.parameters[i].paramID;
        //                        }
        //                        else
        //                        {
        //                            ActionCode += e.parameters[i].type + " " + e.parameters[i].paramID;
        //                            PreCode += e.parameters[i].type + " " + e.parameters[i].paramID;
        //                            paramString += e.parameters[i].type + " " + e.parameters[i].paramID;
        //                            paramList += e.parameters[i].paramID;
        //                        }
        //                        ModelSlicer.BindingType bindingType = mysdes.Slicer.whatIsBindingType(e.ID, e.parameters[i].paramID);
        //                        if (bindingType == ModelSlicer.BindingType.bindedByFunction)
        //                        {

        //                            nois += "\n\t\t\t" + e.ID + "_" + e.parameters[i].paramID + "_ParamList = " +
        //                                    e.ID + "_" + e.parameters[i].paramID + "_ParamGenerator(); "
        //                                    + "\n\t\t\tnumberOfInstances *= " + e.ID + "_" + e.parameters[i].paramID + "_ParamList.Count;";
        //                        }
        //                        else if (bindingType == ModelSlicer.BindingType.bindedByDomin)
        //                        {
        //                            nois += "\n\t\t\t" + e.ID + "_" + e.parameters[i].paramID + "_ParamList = " +
        //                                    mysdes.Slicer.whatIsDomianID(e.ID, e.parameters[i].paramID)
        //                                    + ";\n\t\t\tnumberOfInstances *= " + e.ID + "_" + e.parameters[i].paramID + "_ParamList.Count;";
        //                        }

        //                        extractParams += "\n\t\t\t" + e.parameters[i].type + " " + e.parameters[i].paramID + " = (" + e.parameters[i].type + ")param[\"" + e.parameters[i].paramID + "\"];";

        //                        sl += "\n\t\t\t" + e.parameters[i].type + " " + e.parameters[i].paramID + " = ";
        //                        sl += e.ID + "_" + e.parameters[i].paramID + "_ParamList [ instanceID % " + e.ID + "_" + e.parameters[i].paramID + "_ParamList.Count ];";
        //                        sl += "\n\t\t\tinstanceID /= " + e.ID + "_" + e.parameters[i].paramID + "_ParamList.Count ;";

        //                        sl2 += "\n\t\tparam[\"" + e.parameters[i].paramID + "\"]=" + e.parameters[i].paramID + ";";

        //                    }
        //                    e.paramString = paramString;
        //                    ActionCode += ")" + e.ActionAttrib.Code;
        //                    PreCode += ")" + e.PreCondition.Code;
        //                    //A function to generate parameters and another to gerenare numberofInstance
        //                    nois = "\n\n\t\tint " + e.ID + "_NoI(){" + nois + "\n\t\t\treturn numberOfInstances;}";


        //                    Code += ActionCode + PreCode + nois;
        //                    //Code += "\n\n\t\t" + e.ActionAttrib.Type + " " + e.ID + "_act(int instanceID){" + sl + "\n\t\t\t" + e.ID + "_performAction(" + paramList + ");}";
        //                    Code += "\n\nActionInfo " + e.ID + "_act(int instanceID){ActionInfo param=new ActionInfo(\"" + e.ID + "\");" + sl + "\n\t\t\t" + e.ID + "_performAction(" + paramList + ");" + sl2 + "return param;}";
        //                    Code += "\n\nActionInfo " + e.ID + "_actByParam(ActionInfo param){" + extractParams + "\n\t\t\t" + e.ID + "_performAction(" + paramList + ");" + sl2 + "return param;}";

        //                    //Has "skipping for some transitions"
        //                    if (e.precondition2 == null)
        //                    {
        //                        Code += "\n\n\t\t" + e.PreCondition.Type + " " + e.ID + "_pre(int instanceID){" + sl + "\n\t\t\treturn " + e.ID + "_performPre(" + paramList + ");}";
        //                        Code += "\n\n\t\t" + e.PreCondition.Type + " " + e.ID + "_preByParam(ActionInfo param){" + extractParams + "\n\t\t\treturn " + e.ID + "_performPre(" + paramList + ");}";
        //                    }
        //                    else
        //                    {
        //                        Code += "\n\n\t\t" + e.PreCondition.Type + " " + e.ID + "_preByParam(ActionInfo param){" + extractParams + "\n\t\t\treturn " + e.ID + "_performPre(" + paramList + ")&& " + e.ID + "_performPre2(" + paramList + ");}";
        //                        Code += "\n\n\t\t" + e.PreCondition.Type + " " + e.ID + "_pre(int instanceID){" + sl + "\n\t\t\treturn " + e.ID + "_performPre(" + paramList + ")&& " + e.ID + "_performPre2(" + paramList + ");}";
        //                    }
        //                }


        //                //State dependent weight function
        //                if (e.Weight != null)
        //                    //defined weight function
        //                    Code += "\n\n\t\tfloat " + e.ID + "_wei()" + e.Weight.Code;
        //                else
        //                    //default weight function
        //                    Code += "\n\n\t\tfloat " + e.ID + "_wei(){return 1;}";

        //                /*
        //                                Code += "ExDistribution " + e.ID + "_del(ref bool unbiased)" +
        //                                    e.Delay.Code;
        //                                Code += e.Rank.Type + " " + e.ID + "_rnk()" +
        //                                    e.Rank.Code;
        //                                Code += e.Weight.Type + " " + e.ID + "_wgt()" +
        //                                    e.Weight.Code;
        //                                Code += " bool " + e.ID + @"_rac()" +
        //                                    e.ReActivation.Code;
        //                */
        //                Code += "\n\n\t\t/*--------------------------set handlers---------------------------*/ ";
        //                //Precondition Handler
        //                Code += "\n\t\tpublic EnGine.Formalism.EventsCollection4Test.TestEvent.PreConditionHandler " + e.ID + "_Pre{"
        //                        + "\n\t\t\tget{ return new EnGine.Formalism.EventsCollection4Test.TestEvent.PreConditionHandler(" +
        //                        e.ID + "_pre);}\n\t\t}";

        //                Code += "\n\t\tpublic EnGine.Formalism.EventsCollection4Test.TestEvent.PreConditionByParamHandler " + e.ID + "_PreByParam{"
        //                        + "\n\t\t\tget{ return new EnGine.Formalism.EventsCollection4Test.TestEvent.PreConditionByParamHandler(" +
        //                        e.ID + "_preByParam);}\n\t\t}";

        //                //Weight Handler
        //                Code += "\n\t\tpublic EnGine.Formalism.EventsCollection4Test.TestEvent.WeightHandler " + e.ID + "_Wei{"
        //                        + "\n\t\t\tget{ return new EnGine.Formalism.EventsCollection4Test.TestEvent.WeightHandler(" +
        //                        e.ID + "_wei);}\n\t\t}";
        //                //ActionAttrib Handler
        //                Code += "\n\t\tpublic EnGine.Formalism.EventsCollection4Test.TestEvent.ActionHandler " + e.ID + "_Act{"
        //                        + "\n\t\t\tget{ return new EnGine.Formalism.EventsCollection4Test.TestEvent.ActionHandler(" +
        //                        e.ID + "_act);}\n\t\t}";

        //                Code += "\n\t\tpublic EnGine.Formalism.EventsCollection4Test.TestEvent.ActionByParamHandler " + e.ID + "_ActByParam{"
        //                         + "\n\t\t\tget{ return new EnGine.Formalism.EventsCollection4Test.TestEvent.ActionByParamHandler(" +
        //                         e.ID + "_actByParam);}\n\t\t}";

        //                //Param generator Handler
        //                Code += "\n\t\tpublic EnGine.Formalism.EventsCollection4Test.TestEvent.NumberOfActionInstancesHandler " +
        //                        e.ID + "_NOI{"
        //                        + "\n\t\t\tget{ return new EnGine.Formalism.EventsCollection4Test.TestEvent.NumberOfActionInstancesHandler(" + e.ID + "_NoI);}\n\t\t}";


        //                /*
        //                                Code += "public EnGine.Formalism.EventsCollection4Test.TestEvent.ISDelayHandler " + e.ID + @"_Del
        //                                        {
        //                                            get{                                            return new EnGine.Formalism.EventsCollection4Test.TestEvent.ISDelayHandler(" + e.ID + @"_del);
        //                                            }
        //                                        }";
        //                                Code += "public EnGine.Formalism.EventsCollection4Test.TestEvent.RankHandler " + e.ID + @"_Rnk
        //                                        {
        //                                            get{
        //                                            return new EnGine.Formalism.EventsCollection4Test.TestEvent.RankHandler(" + e.ID + @"_rnk);
        //                                            }
        //                                        }";
        //                                Code += "public EnGine.Formalism.EventsCollection4Test.TestEvent.ReActivationHandler " + e.ID + @"_Rac
        //                                        {
        //                                            get{
        //                                            return new EnGine.Formalism.EventsCollection4Test.TestEvent.ReActivationHandler(" + e.ID + @"_rac);
        //                                            }
        //                                        }";
        //                                Code += "public EnGine.Formalism.EventsCollection4Test.TestEvent.WeightHandler " + e.ID + @"_Wgt
        //                                        {
        //                                            get{
        //                                            return new EnGine.Formalism.EventsCollection4Test.TestEvent.WeightHandler(" + e.ID + @"_wgt);
        //                                            }
        //                                        }";
        //                  */


        //            }
        //            #endregion

        //            #region State Check and Binding
        //            Code += "\n/***********************************************************************/";

        //            Code += "\n\t\tpublic bool isFinalState()" + mysdes.Variables.isFinalState.Code;
        //            Code += "\n\t\tbool isValidState()" + mysdes.Variables.isValidState.Code;
        //            Code += "\n\t\tpublic bool skipState   ()" + mysdes.Slicer.SkipState;
        //            Code += "\n\t\tpublic void ValidateCurrentState() {if(!isValidState()) "
        //                    + "throw new Exception(\"Not a valid state!.\"); }";

        //            //for (int i = 0; i < mysdes.Events.Events.Count; i++)
        //            //{

        //            //}


        //            for (int i = 0; i < mysdes.Slicer.paramBindersOfModel.Count; i++)
        //            {
        //                string tmpstr = "";
        //                for (int j = 0; j < mysdes.Slicer.paramBindersOfModel[i].bindingFunctionList.Count; j++)
        //                {
        //                    //A function to generate one parameter
        //                    tmpstr += "\n\t\tList<" + mysdes.Slicer.paramBindersOfModel[i].bindingFunctionList[j].parmType + "> "
        //                            + mysdes.Slicer.paramBindersOfModel[i].inAction + "_" + mysdes.Slicer.paramBindersOfModel[i].bindingFunctionList[j].paramID + "_ParamGenerator()"
        //                            + mysdes.Slicer.paramBindersOfModel[i].bindingFunctionList[j].BindingFunction;
        //                }
        //                Code += tmpstr;
        //            }
        //            for (int i = 0; i < mysdes.Slicer.skipTransitionFunctions.Count; i++)
        //            {
        //                if (mysdes.Events[mysdes.Slicer.skipTransitionFunctions[i].Tag] != null)
        //                    Code += "\n\t\tbool "
        //                        + mysdes.Slicer.skipTransitionFunctions[i].Tag + "_performPre2(" + mysdes.Events[mysdes.Slicer.skipTransitionFunctions[i].Tag].paramString + ")"
        //                            + mysdes.Slicer.skipTransitionFunctions[i].Code;

        //            }
        //            #endregion
        //            Code += @"
        //}
        //" + StateCode + @"
        //}";


        //            generatedCode = Code;
        //            return Code;
        //            //            int[] rr = new int[6];
        //            //            ICodeCompiler loCompiler = new CSharpCodeProvider().CreateCompiler();
        //            //            CompilerParameters loParameters = new CompilerParameters();

        //            //            loParameters.ReferencedAssemblies.Add("System.dll");
        //            //            loParameters.ReferencedAssemblies.Add("\\SimGine.dll");

        //            //            File.WriteAllText("c:\\2.cs", Code);

        //            //            #region compiling
        //            //            // *** Load the resulting assembly into memory

        //            //            loParameters.GenerateInMemory = false;

        //            //            // *** Now compile the whole thing

        //            //            List<string> sources = new List<string>();
        //            //            sources.Add(Code);
        //            //            foreach (string file in mysdes.AUX.Headers)
        //            //                sources.Add(File.ReadAllText(file));
        //            //            CompilerResults loCompiled =

        //            //                    loCompiler.CompileAssemblyFromSourceBatch(loParameters, sources.ToArray());

        //            //            if (loCompiled.Errors.HasErrors)
        //            //            {

        //            //                string lcErrorMsg = "";



        //            //                lcErrorMsg = loCompiled.Errors.Count.ToString() + " Errors:";

        //            //                for (int x = 0; x < loCompiled.Errors.Count; x++)

        //            //                    if (!loCompiled.Errors[x].IsWarning)
        //            //                        lcErrorMsg = lcErrorMsg + "\r\nLine: " +

        //            //                                     loCompiled.Errors[x].Line.ToString() + " - " +

        //            //                                     loCompiled.Errors[x].ErrorText;
        //            //#if DEBUG
        //            //                //if (MessageBox.Show("Compile Error.Do you want to save Generated Code?", "Compile Error", MessageBoxButtons.YesNo)
        //            //                //    == DialogResult.Yes)
        //            //                //{
        //            //                //    SaveFileDialog dlg = new SaveFileDialog();
        //            //                //    dlg.DefaultExt = ".txt";
        //            //                //    if (dlg.ShowDialog() == DialogResult.OK)
        //            //                //    {
        //            //                //        File.WriteAllText(dlg.FileName, Code);
        //            //                //        File.AppendAllText(dlg.FileName, ("\n***************************************\n" + lcErrorMsg));
        //            //                //    }
        //            //                //    return false;
        //            //                //}
        //            //#endif
        //            //                return true;
        //            //            }

        //            //            #endregion

        //        }



    }
}
